package org.phoenixframework.oauth2.server.config.security;

import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import org.phoenixframework.common.entity.SysRole;
import org.phoenixframework.common.entity.SysUser;
import org.phoenixframework.oauth2.server.constant.AuthConstant;
import org.phoenixframework.oauth2.server.entity.SecurityUser;
import org.phoenixframework.oauth2.server.service.ISysResourceService;
import org.phoenixframework.oauth2.server.service.ISysRoleService;
import org.phoenixframework.oauth2.server.service.ISysUserService;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by IntelliJ IDEA.
 *
 * @author doublelifeke
 * Email: hautxxxyzjk@163.com
 * DateTime: 2021/6/7 17:10
 * Description:
 */
@AllArgsConstructor
@Component
public class UserDetailsServiceImpl implements UserDetailsService {

    private final ISysUserService sysUserService;

    private final ISysRoleService sysRoleService;

    private final ISysResourceService sysResourceService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 用户信息
        SysUser sysUser = sysUserService.findByUsername(username);
        if (ObjectUtil.isEmpty(sysUser)) {
            throw new UsernameNotFoundException(AuthConstant.USERNAME_PASSWORD_ERROR);
        }
        // 获取用户拥有的角色 和 用户拥有的资源访问路径（后台接口地址）
        List<SysRole> sysRoles;
        if (sysUser.getIsSuper() == 1) {
            sysRoles = sysRoleService.list();
        } else {
            sysRoles = sysRoleService.listBySysUserId(sysUser.getId());
        }
        List<String> roles = sysRoles.stream()
                .map(item -> item.getId() + "_" + item.getCode())
                .collect(Collectors.toList());
        List<GrantedAuthority> authorities = new ArrayList<>();
        roles.forEach(item -> authorities.add(new SimpleGrantedAuthority(item)));
        SecurityUser securityUser = new SecurityUser(sysUser, authorities);

        if (!securityUser.isEnabled()) {
            throw new DisabledException(AuthConstant.ACCOUNT_DISABLED);
        } else if (!securityUser.isAccountNonLocked()) {
            throw new LockedException(AuthConstant.ACCOUNT_LOCKED);
        } else if (!securityUser.isAccountNonExpired()) {
            throw new AccountExpiredException(AuthConstant.ACCOUNT_EXPIRED);
        } else if (!securityUser.isCredentialsNonExpired()) {
            throw new CredentialsExpiredException(AuthConstant.CREDENTIALS_EXPIRED);
        }
        return securityUser;
    }

}
